package com.example.mcp.tool;

import com.example.mcp.service.McpClientService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 严格的MCP客户端AI工具 - 完全阻止重复调用
 * 一旦被调用，立即禁用，直到下次会话
 */
@Component
public class StrictMcpClientTool implements FunctionCallback {

    private static final Logger logger = LoggerFactory.getLogger(StrictMcpClientTool.class);

    @Autowired
    private McpClientService mcpClientService;

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    // 防止重复调用：记录每个请求周期的调用次数
    private final ThreadLocal<Integer> callCount = ThreadLocal.withInitial(() -> 0);
    private final ThreadLocal<Long> requestStartTime = ThreadLocal.withInitial(() -> 0L);
    
    // 每个请求周期的超时时间（秒）- 超过这个时间重置计数
    private static final long REQUEST_TIMEOUT_SECONDS = 60;

    @Override
    public String getName() {
        return "mcpClient";
    }

    @Override
    public String getDescription() {
        return "MCP客户端工具，可以获取聊天记录、发送消息、检查连接状态等（严格模式：只能调用一次）";
    }

    @Override
    public String getInputTypeSchema() {
        return """
            {
                "type": "object",
                "properties": {
                    "action": {
                        "type": "string",
                        "description": "操作类型：getAllConversations(获取所有聊天记录), getConversationById(获取特定聊天记录), getMessages(获取消息列表), sendMessage(发送消息), ping(测试连接), health(检查健康状态)",
                        "enum": ["getAllConversations", "getConversationById", "getMessages", "sendMessage", "ping", "health"]
                    },
                    "conversationId": {
                        "type": "string",
                        "description": "聊天记录ID（某些操作需要）"
                    },
                    "sender": {
                        "type": "string",
                        "description": "发送者名称（发送消息时需要）"
                    },
                    "content": {
                        "type": "string",
                        "description": "消息内容（发送消息时需要）"
                    }
                },
                "required": ["action"]
            }
            """;
    }

    @Override
    public String call(String functionArguments) {
        logger.info("🤖 AI调用MCP客户端工具 call()===========================================================" );
        
        // 🔥 防止重复调用的硬性限制
        long currentTime = System.currentTimeMillis() / 1000;
        long startTime = requestStartTime.get();
        
        // 如果是新请求（超时）或第一次调用，重置计数
        if (startTime == 0 || (currentTime - startTime) > REQUEST_TIMEOUT_SECONDS) {
            callCount.set(0);
            requestStartTime.set(currentTime);
            logger.info("🔄 新的请求周期开始");
        }
        
        // 增加调用计数
        int currentCount = callCount.get() + 1;
        callCount.set(currentCount);
        
        logger.info("📊 当前调用次数: {}/1", currentCount);
        
        // 如果已经调用过一次，直接返回拒绝信息
        if (currentCount > 1) {
            String rejectMessage = String.format(
                "⛔ 工具调用已达到限制！此工具在当前请求中已被调用 %d 次。" +
                "请直接使用之前的工具返回结果回答用户，不要再次调用工具。", 
                currentCount - 1
            );
            logger.warn(rejectMessage);
            return rejectMessage;
        }
        
        try {
            logger.info("🤖 AI调用MCP客户端工具（严格模式），参数: {}", functionArguments);
            
            // 解析JSON参数
            JsonNode args = objectMapper.readTree(functionArguments);
            String action = args.get("action").asText();
            
            String result;
            
            switch (action) {
                case "getAllConversations":
                    result = getAllConversations();
                    break;
                case "getConversationById":
                    String conversationId = args.has("conversationId") ? args.get("conversationId").asText() : "1";
                    result = getConversationById(conversationId);
                    break;
                case "getMessages":
                    String msgConversationId = args.has("conversationId") ? args.get("conversationId").asText() : "1";
                    result = getMessagesByConversationId(msgConversationId);
                    break;
                case "sendMessage":
                    String sendConversationId = args.has("conversationId") ? args.get("conversationId").asText() : "1";
                    String sender = args.has("sender") ? args.get("sender").asText() : "AI助手";
                    String content = args.has("content") ? args.get("content").asText() : "这是一条AI发送的测试消息";
                    result = sendMessage(sendConversationId, sender, content);
                    break;
                case "ping":
                    result = ping();
                    break;
                case "health":
                    result = checkHealth();
                    break;
                default:
                    result = "错误：不支持的操作 '" + action + "'。支持的操作：getAllConversations, getConversationById, getMessages, sendMessage, ping, health";
            }
            
            // 确保返回的结果是有效的字符串，避免JSON解析错误
            if (result == null || result.trim().isEmpty()) {
                result = "操作完成，但没有返回数据";
            }
            
            logger.info("✅ MCP客户端工具执行完成（严格模式）: {}", result);
            return result;
            
        } catch (Exception e) {
            logger.error("❌ MCP客户端工具执行失败（严格模式）", e);
            return "错误: " + e.getMessage();
        }
    }

    /**
     * 获取所有聊天记录
     */
    private String getAllConversations() {
        try {
            logger.info("🤖 AI调用: 获取所有聊天记录");
            String result = mcpClientService.getAllConversations().get();
            return result != null ? result : "没有找到聊天记录";
        } catch (Exception e) {
            logger.error("❌ AI调用获取聊天记录失败", e);
            return "获取聊天记录失败: " + e.getMessage();
        }
    }

    /**
     * 根据ID获取聊天记录
     */
    private String getConversationById(String conversationId) {
        try {
            logger.info("🤖 AI调用: 获取聊天记录详情 - ID: {}", conversationId);
            String result = mcpClientService.getConversationById(conversationId).get();
            return result != null ? result : "没有找到ID为 " + conversationId + " 的聊天记录";
        } catch (Exception e) {
            logger.error("❌ AI调用获取聊天记录详情失败", e);
            return "获取聊天记录详情失败: " + e.getMessage();
        }
    }

    /**
     * 获取会话消息列表
     */
    private String getMessagesByConversationId(String conversationId) {
        try {
            logger.info("🤖 AI调用: 获取会话消息列表 - ID: {}", conversationId);
            String result = mcpClientService.getMessagesByConversationId(conversationId).get();
            return result != null ? result : "会话 " + conversationId + " 中没有消息";
        } catch (Exception e) {
            logger.error("❌ AI调用获取消息列表失败", e);
            return "获取消息列表失败: " + e.getMessage();
        }
    }

    /**
     * 发送消息
     */
    private String sendMessage(String conversationId, String sender, String content) {
        try {
            logger.info("🤖 AI调用: 发送消息 - 会话ID: {}, 发送者: {}", conversationId, sender);
            String result = mcpClientService.sendMessage(conversationId, sender, content).get();
            return result != null ? result : "消息发送成功";
        } catch (Exception e) {
            logger.error("❌ AI调用发送消息失败", e);
            return "发送消息失败: " + e.getMessage();
        }
    }

    /**
     * Ping测试
     */
    private String ping() {
        try {
            logger.info("🤖 AI调用: Ping测试MCP服务器");
            String result = mcpClientService.ping().get();
            return result != null ? result : "Ping测试成功";
        } catch (Exception e) {
            logger.error("❌ AI调用Ping测试失败", e);
            return "Ping测试失败: " + e.getMessage();
        }
    }

    /**
     * 检查健康状态
     */
    private String checkHealth() {
        try {
            logger.info("🤖 AI调用: 检查MCP客户端健康状态");
            boolean isHealthy = mcpClientService.isInitialized();
            return "MCP客户端状态: " + (isHealthy ? "健康" : "异常");
        } catch (Exception e) {
            logger.error("❌ AI调用健康检查失败", e);
            return "错误: " + e.getMessage();
        }
    }
    
    /**
     * 重置工具调用计数（用于新的请求周期）
     * 可以在请求开始时主动调用，确保计数正确
     */
    public void resetCallCount() {
        callCount.set(0);
        requestStartTime.set(System.currentTimeMillis() / 1000);
        logger.info("🔄 手动重置工具调用计数");
    }
    
    /**
     * 清理ThreadLocal资源（防止内存泄漏）
     */
    public void cleanup() {
        callCount.remove();
        requestStartTime.remove();
    }
    
}
